#include <ev.h>
#include <amqpcpp.h>
#include <amqpcpp/libev.h>
#include <openssl/ssl.h>
#include <openssl/opensslv.h>


int main()
{
    //实例化底层网络通信框架的IO事件监控句柄
    auto* loop = EV_DEFAULT;
    //实例化libEvHandler句柄 -- 将AMQP框架与事件监控关联起来
    AMQP::LibEvHandler handler(loop);
    //实例化连接对象
    AMQP::Address address("amqp://root:123456@127.0.0.1:5672/");
    AMQP::TcpConnection connection(&handler, address);
    //实例化信道对象
    AMQP::TcpChannel channel(&connection);

    //4,声明交换机
    channel.declareExchange("test-exchange", AMQP::ExchangeType::direct)
        .onError([](const char* message){
            std::cout << "声明交换机失败: " << message << std::endl;
        }).onSuccess([](){
            std::cout << "test-exchange 交换机创建成功" << std::endl;
        });

    //5,声明队列
    channel.declareQueue("test-queue")
        .onError([](const char* message){
            std::cout << "声明队列失败: " << message << std::endl;
            exit(0);
        })
        .onSuccess([](){
            std::cout << "test-queue 队列创建成功! " << std::endl;
        });
    
    //6, 针对交换机和队列进行绑定
    channel.bindQueue("test-exchange", "test-queue", "test-queue-key")
        .onError([](const char* message){
            std::cout << "绑定失败: " << message << std::endl;
            exit(0);
        })
        .onSuccess([](){
            std::cout << "交换机和队列绑定成功" << std::endl;
        });

        
    for(int i = 0; i < 10; i++)
    {
        std::string msg = "hello word-" + std::to_string(i);
        // bool publish(const std::string_view &exchange, const std::string_view &routingKey, const std::string &message, int flags = 0)
        bool ret = channel.publish("test-exchange", "test-queue-key", msg);
        if(ret == false)
        {
            std::cout << "publish失败" << std::endl;
        }
        else
        {
            std::cout << "publish成功" << std::endl;
        }
    }


    ev_run(loop, 0);
    //启动底层网络通信框架 -- 开启IO

    return 0;
}

//问题：为什么先打印publish成功, 后打印交换机，队列创建成功，交换机和队列绑定成功这些呢
//原因：异步的声明/绑定请求已发送，但 RabbitMQ 尚未返回响应。没有调用ev_run，网络IO未被处理，回调不会触发
//而publish打印，是将消息写入本地缓冲区，由库在后台通过 TCP 发送， 他会立刻返回true


// #include <ev.h>
// #include <amqpcpp.h>
// #include <amqpcpp/libev.h>
// #include <openssl/ssl.h>
// #include <openssl/opensslv.h>

// int main()
// {
//     //1. 实例化底层网络通信框架的I/O事件监控句柄
//     auto *loop = EV_DEFAULT;
//     //2. 实例化libEvHandler句柄 --- 将AMQP框架与事件监控关联起来
//     AMQP::LibEvHandler handler(loop);
//     //2.5. 实例化连接对象
//     AMQP::Address address("amqp://root:123456@127.0.0.1:5672/");
//     AMQP::TcpConnection connection(&handler, address);
//     //3. 实例化信道对象
//     AMQP::TcpChannel channel(&connection);
//     //4. 声明交换机
//     channel.declareExchange("test-exchange", AMQP::ExchangeType::direct)
//         .onError([](const char *message) {
//             std::cout << "声明交换机失败：" << message << std::endl;
//             exit(0);
//         })
//         .onSuccess([](){
//             std::cout << "test-exchange 交换机创建成功！" << std::endl;
//         });
//     //5. 声明队列
//     channel.declareQueue("test-queue")
//         .onError([](const char *message) {
//             std::cout << "声明队列失败：" << message << std::endl;
//             exit(0);
//         })
//         .onSuccess([](){
//             std::cout << "test-queue 队列创建成功！" << std::endl;
//         });
//     //6. 针对交换机和队列进行绑定
//     channel.bindQueue("test-exchange", "test-queue", "test-queue-key")
//         .onError([](const char *message) {
//             std::cout << "test-exchange - test-queue 绑定失败：" << message << std::endl;
//             exit(0);
//         })
//         .onSuccess([](){
//             std::cout << "test-exchange - test-queue 绑定成功！" << std::endl;
//         });
//     //7. 向交换机发布消息
//     for (int i = 0; i < 10; i++) {
//         std::string msg = "Hello Bite-" + std::to_string(i);
//         bool ret = channel.publish("test-exchange", "test-queue-key", msg);
//         if (ret == false) {
//             std::cout << "publish 失败！\n";
//         }
//     }
//     //启动底层网络通信框架--开启I/O
//     ev_run(loop, 0);
//     return 0;
// }